using GameLogic;
using System;
using TEngine;
using UnityEngine;
using Random = UnityEngine.Random;

[System.Serializable]
public class PhaseDuration
{
    public float 凌晨占比;
    public float 白天占比;
    public float 黄昏占比;
    public float 夜晚占比;
}

[System.Serializable]
public class SeasonSettings
{
    public int springDays = 15;
    public int summerDays = 10;
    public int autumnDays = 15;
    public int winterDays = 10;

    [Header("各季节时间段分布 [季节, 时段]")]
    public float[,] seasonPhaseDistribution = new float[4, 4] {
        /* 春天 */ { 0.35f, 0.30f, 0.20f, 0.15f }, // 凌晨多
        /* 夏天 */ { 0.20f, 0.40f, 0.25f, 0.15f }, // 白天多
        /* 秋天 */ { 0.15f, 0.25f, 0.40f, 0.20f }, // 黄昏多
        /* 冬天 */ { 0.15f, 0.20f, 0.25f, 0.40f }  // 夜晚多
    };

    // 获取当前季节的时间段占比
    public PhaseDuration GetCurrentPhaseDuration(Season season)
    {
        int seasonIndex = (int)season;
        return new PhaseDuration
        {
            凌晨占比 = seasonPhaseDistribution[seasonIndex, 0],
            白天占比 = seasonPhaseDistribution[seasonIndex, 1],
            黄昏占比 = seasonPhaseDistribution[seasonIndex, 2],
            夜晚占比 = seasonPhaseDistribution[seasonIndex, 3]
        };
    }
}

[System.Serializable]
public class WeatherSettings
{
    [Header("天气变化设置")]
    public float weatherChangeChance = 0.01f;
    public int minWeatherDuration = 30;
    public int maxWeatherDuration = 240;

    [Header("季节天气概率 [季节, 天气]")]
    public float[,] seasonWeatherProbabilities = new float[4, 8] {
        /* 春天 */ { 0.3f, 0.3f, 0.2f, 0.1f, 0.05f, 0f, 0f, 0.05f },
        /* 夏天 */ { 0.4f, 0.2f, 0.1f, 0.15f, 0.1f, 0f, 0f, 0.05f },
        /* 秋天 */ { 0.4f, 0.3f, 0.1f, 0.1f, 0.05f, 0f, 0f, 0.05f },
        /* 冬天 */ { 0.2f, 0.2f, 0f, 0f, 0f, 0.3f, 0.2f, 0.1f }
    };
}

public class EnhancedTimeWeatherSystem : SingletonBehaviour<EnhancedTimeWeatherSystem>
{
    [Header("当前时间信息 (只读)")]
    [SerializeField] private int displaySecond;
    [SerializeField] private int displayDay;
    [SerializeField] private int displayMonth;
    [SerializeField] private int displayYear;
    [SerializeField] private Season displaySeason;
    [SerializeField] private DayPhase displayDayPhase;
    [SerializeField] private string displaySeasonProgress;
    [SerializeField] private string displayDayProgress;
    [SerializeField] private Weather displayWeather;
    [SerializeField] private string displayTimeString;
    [SerializeField] private string displayDateString;

    [Header("时间段占比信息 (只读)")]
    [SerializeField] private float 凌晨占比;
    [SerializeField] private float 白天占比;
    [SerializeField] private float 黄昏占比;
    [SerializeField] private float 夜晚占比;
    [SerializeField] private int 凌晨持续时间;
    [SerializeField] private int 白天持续时间;
    [SerializeField] private int 黄昏持续时间;
    [SerializeField] private int 夜晚持续时间;
    [SerializeField] private string 时间段分布信息;

    [Header("当前时间段信息 (只读)")]
    [SerializeField] private int 当前时间段开始秒;
    [SerializeField] private int 当前时间段结束秒;
    [SerializeField] private int 当前时间段剩余秒;
    [SerializeField] private float 当前时间段进度;

    [Header("时间设置")]
    private int gameSecond;      // 游戏秒数 (0-479, 共480秒=8分钟=1天)
    private int gameDay;         // 游戏天数
    private int gameMonth;       // 游戏月份
    private int gameYear;        // 游戏年份
    private Season gameSeason = Season.春天;
    private int daysInCurrentSeason;
    private DayPhase currentDayPhase = DayPhase.凌晨;
    public bool gameClockPause=true;
    private float tikTime;

    [Header("时间比例设置")]
    [SerializeField] private float realSecondsPerGameSecond = 1.0f; // 现实1秒 = 游戏1秒
    [SerializeField] private float realSecondsPerGameDay = 480f;    // 现实480秒(8分钟) = 游戏1天

    [Header("季节设置")]
    public SeasonSettings seasonSettings = new SeasonSettings();

    [Header("天气设置")]
    public WeatherSettings weatherSettings = new WeatherSettings();
    private Weather currentWeather = Weather.晴朗;
    private int currentWeatherDuration;
    private int weatherChangeCountdown;

    [Header("时间流速")]
    [SerializeField] private float timeScale = 1.0f;

    private int[] phaseStartSeconds = new int[4]; // 每个时间段的开始秒数
    private int[] phaseEndSeconds = new int[4];   // 每个时间段的结束秒数

    // 事件
    public static event Action<string> OnSeasonProgressChanged;

    public void Init()
    {
        gameClockPause = true;
        InitializeTimeAndWeather();
        UpdateInspectorDisplay();
        StartTime();
    }

    public void StartTime()
    {
        gameClockPause = false;
    }

    private void Update()
    {
        if (!gameClockPause)
        {
            tikTime += Time.deltaTime * timeScale;

            // 根据现实时间推进游戏时间
            if (tikTime >= realSecondsPerGameSecond)
            {
                int secondsToAdvance = Mathf.FloorToInt(tikTime / realSecondsPerGameSecond);
                tikTime %= realSecondsPerGameSecond;

                for (int i = 0; i < secondsToAdvance; i++)
                {
                    UpdateGameTime();
                }
            }
        }

        HandleDebugInput();
        UpdateInspectorDisplay();
    }

    // 更新Inspector面板显示
    private void UpdateInspectorDisplay()
    {
        if (gameClockPause) return;
        displaySecond = gameSecond;
        displayDay = gameDay;
        displayMonth = gameMonth;
        displayYear = gameYear;
        displaySeason = gameSeason;
        displayDayPhase = currentDayPhase;
        displayWeather = currentWeather;

        // 格式化时间显示
        int currentMinute = gameSecond / 60;
        int currentSecond = gameSecond % 60;
        displayTimeString = $"{currentDayPhase} {currentMinute:00}:{currentSecond:00}";
        displayDateString = $"{gameYear}年{gameMonth:00}月{gameDay:00}日";

        // 显示天进度
        float dayProgress = (float)gameSecond / realSecondsPerGameDay * 100f;
        displayDayProgress = $"天进度: {dayProgress:F1}% ({gameSecond}s / {realSecondsPerGameDay}s)";

        // 更新时间段占比信息
        UpdatePhaseInfoDisplay();
    }

    private void UpdatePhaseInfoDisplay()
    {
        if (gameClockPause) return;
        // 获取当前季节的时间段占比
        PhaseDuration phaseDuration = seasonSettings.GetCurrentPhaseDuration(gameSeason);
        凌晨占比 = phaseDuration.凌晨占比;
        白天占比 = phaseDuration.白天占比;
        黄昏占比 = phaseDuration.黄昏占比;
        夜晚占比 = phaseDuration.夜晚占比;

        // 计算每个时间段的持续时间（秒）
        凌晨持续时间 = Mathf.RoundToInt(realSecondsPerGameDay * 凌晨占比);
        白天持续时间 = Mathf.RoundToInt(realSecondsPerGameDay * 白天占比);
        黄昏持续时间 = Mathf.RoundToInt(realSecondsPerGameDay * 黄昏占比);
        夜晚持续时间 = Mathf.RoundToInt(realSecondsPerGameDay * 夜晚占比);

        // 计算时间段的开始和结束秒数
        phaseStartSeconds[0] = 0;
        phaseEndSeconds[0] = 凌晨持续时间;

        phaseStartSeconds[1] = phaseEndSeconds[0];
        phaseEndSeconds[1] = phaseStartSeconds[1] + 白天持续时间;

        phaseStartSeconds[2] = phaseEndSeconds[1];
        phaseEndSeconds[2] = phaseStartSeconds[2] + 黄昏持续时间;

        phaseStartSeconds[3] = phaseEndSeconds[2];
        phaseEndSeconds[3] = phaseStartSeconds[3] + 夜晚持续时间;

        // 格式化时间段分布信息
        时间段分布信息 = $"{gameSeason}时间段分布:\n" +
                      $"凌晨: {凌晨占比 * 100:F1}% ({凌晨持续时间}s)\n" +
                      $"白天: {白天占比 * 100:F1}% ({白天持续时间}s)\n" +
                      $"黄昏: {黄昏占比 * 100:F1}% ({黄昏持续时间}s)\n" +
                      $"夜晚: {夜晚占比 * 100:F1}% ({夜晚持续时间}s)";

        // 更新当前时间段信息
        UpdateCurrentPhaseInfo();
    }

    private void UpdateCurrentPhaseInfo()
    {
        int currentPhaseIndex = (int)currentDayPhase;
        当前时间段开始秒 = phaseStartSeconds[currentPhaseIndex];
        当前时间段结束秒 = phaseEndSeconds[currentPhaseIndex];
        当前时间段剩余秒 = 当前时间段结束秒 - gameSecond;

        if (当前时间段剩余秒 < 0) 当前时间段剩余秒 = 0;

        int phaseDuration = 当前时间段结束秒 - 当前时间段开始秒;
        if (phaseDuration > 0)
        {
            当前时间段进度 = (float)(gameSecond - 当前时间段开始秒) / phaseDuration * 100f;
        }
        else
        {
            当前时间段进度 = 0f;
        }
        //GameEvent.Get<ILoginUI>().OnTimerChange();
    }

    private void InitializeTimeAndWeather()
    {
        daysInCurrentSeason = GetSeasonDays(gameSeason);
        UpdatePhaseInfoDisplay(); // 先计算时间段信息
        currentDayPhase = GetCurrentDayPhase(); // 再确定当前时间段

        currentWeatherDuration = Random.Range(weatherSettings.minWeatherDuration, weatherSettings.maxWeatherDuration);
        weatherChangeCountdown = Random.Range(10, 60);

        UpdateSeasonProgress();
        UpdateLighting();
        UpdateInspectorDisplay();
    }

    private int GetSeasonDays(Season season)
    {
        switch (season)
        {
            case Season.春天: return seasonSettings.springDays;
            case Season.夏天: return seasonSettings.summerDays;
            case Season.秋天: return seasonSettings.autumnDays;
            case Season.冬天: return seasonSettings.winterDays;
            default: return 15;
        }
    }

    private int GetTotalDaysInYear()
    {
        return seasonSettings.springDays + seasonSettings.summerDays +
               seasonSettings.autumnDays + seasonSettings.winterDays;
    }

    private void UpdateGameTime()
    {
        gameSecond++;
        GameEvent.Get<ILoginUI>().OnTimerChange();
        // 检查是否需要切换时间段
        CheckDayPhaseChange();

        // 8分钟(480秒) = 1天
        if (gameSecond >= realSecondsPerGameDay)
        {
            gameSecond = 0;
            gameDay++;
            daysInCurrentSeason--;
            OnDayPassed();
        }

        // 检查季节是否结束
        if (daysInCurrentSeason <= 0)
        {
            AdvanceToNextSeason();
        }

        // 计算月份（每30天一个月）
        gameMonth = (gameDay / 30) + 1;
        if (gameMonth > 12)
        {
            gameMonth = 1;
        }

        // 计算年份
        int totalDaysInYear = GetTotalDaysInYear();
        gameYear = 2022 + (gameDay / totalDaysInYear);

        UpdateInspectorDisplay();
    }

    private void CheckDayPhaseChange()
    {
        // 根据计算好的时间段边界确定当前时间段
        DayPhase newPhase = GetCurrentDayPhase();
        if (newPhase != currentDayPhase)
        {
            currentDayPhase = newPhase;
            UpdateLighting();
        }
    }

    private DayPhase GetCurrentDayPhase()
    {
        // 根据计算好的时间段边界确定当前时间段
        for (int i = 0; i < 4; i++)
        {
            if (gameSecond >= phaseStartSeconds[i] && gameSecond < phaseEndSeconds[i])
            {
                return (DayPhase)i;
            }
        }

        // 默认返回夜晚（处理边界情况）
        return DayPhase.夜晚;
    }

    private void OnDayPassed()
    {
        GameEvent.Get<ILoginUI>().OnDayChange();
        UpdateSeasonProgress();
        UpdateInspectorDisplay();
    }

    private void AdvanceToNextSeason()
    {
        int nextSeason = ((int)gameSeason + 1) % 4;
        gameSeason = (Season)nextSeason;
        daysInCurrentSeason = GetSeasonDays(gameSeason);
        GameEvent.Get<ILoginUI>().OnSeasonChange();
        RollNewWeather(true);
        UpdateSeasonProgress();
        UpdateInspectorDisplay();
    }

    private void UpdateWeather()
    {
        if (currentWeatherDuration <= 0)
        {
            RollNewWeather(false);
            return;
        }

        weatherChangeCountdown--;
        currentWeatherDuration--;

        if (weatherChangeCountdown <= 0)
        {
            if (Random.value < weatherSettings.weatherChangeChance)
            {
                RollNewWeather(false);
            }
            else
            {
                weatherChangeCountdown = Random.Range(30, 120);
            }
        }
    }

    private void RollNewWeather(bool forceChange)
    {
        Weather newWeather = Weather.晴朗;

        if (forceChange || Random.value < 0.7f)
        {
            int seasonIndex = (int)gameSeason;
            float randomValue = Random.value;
            float cumulative = 0f;

            for (int i = 0; i < 8; i++)
            {
                cumulative += weatherSettings.seasonWeatherProbabilities[seasonIndex, i];
                if (randomValue <= cumulative)
                {
                    newWeather = (Weather)i;
                    break;
                }
            }
        }
        else
        {
            newWeather = (Weather)Random.Range(0, 8);
        }

        if (newWeather == currentWeather && !forceChange)
        {
            currentWeatherDuration += Random.Range(30, 120);
        }
        else
        {
            currentWeather = newWeather;
            currentWeatherDuration = Random.Range(weatherSettings.minWeatherDuration, weatherSettings.maxWeatherDuration);
            weatherChangeCountdown = Random.Range(30, 120);

            GameEvent.Get<ILoginUI>().OnDayChange();
        }

        UpdateInspectorDisplay();
    }

    private void UpdateLighting()
    {
        // 根据季节和时间段计算光照效果
        float timeRatio = (float)gameSecond / realSecondsPerGameDay;
        UpdateInspectorDisplay();
    }

    private void UpdateSeasonProgress()
    {
        int totalDays = GetSeasonDays(gameSeason);
        int passedDays = totalDays - daysInCurrentSeason;
        displaySeasonProgress = $"{gameSeason} 第{passedDays + 1}天/共{totalDays}天";
        OnSeasonProgressChanged?.Invoke(displaySeasonProgress);
    }

    public void SetTimeScale(float scale)
    {
        timeScale = Mathf.Clamp(scale, 0.1f, 10f);
    }

    public void AdvanceTime(int days = 0, int seconds = 0)
    {
        int totalSeconds = days * (int)realSecondsPerGameDay + seconds;
        for (int i = 0; i < totalSeconds; i++)
        {
            UpdateGameTime();
        }
        UpdateInspectorDisplay();
    }

    // 公共方法获取时间段信息
    public PhaseDuration GetCurrentPhaseDuration()
    {
        return seasonSettings.GetCurrentPhaseDuration(gameSeason);
    }

    public int GetPhaseDuration(DayPhase phase)
    {
        switch (phase)
        {
            case DayPhase.凌晨: return 凌晨持续时间;
            case DayPhase.白天: return 白天持续时间;
            case DayPhase.黄昏: return 黄昏持续时间;
            case DayPhase.夜晚: return 夜晚持续时间;
            default: return 0;
        }
    }

    public (int start, int end) GetPhaseTimeRange(DayPhase phase)
    {
        int index = (int)phase;
        return (phaseStartSeconds[index], phaseEndSeconds[index]);
    }

    public string GetPhaseInfoString()
    {
        return 时间段分布信息;
    }

    private void HandleDebugInput()
    {
        // 使用 GetKeyDown 替代 GetKey，确保只触发一次
        if (Input.GetKeyDown(KeyCode.T))
        {
            AdvanceTime(0, 60); // 按一次T键前进60秒
        }

        if (Input.GetKeyDown(KeyCode.G))
        {
            AdvanceTime(1, 0); // 前进1天
        }

        if (Input.GetKeyDown(KeyCode.H))
        {
            RollNewWeather(true);
        }

        if (Input.GetKeyDown(KeyCode.P))
        {
            gameClockPause = !gameClockPause; // 改为切换暂停状态
        }

        if (Input.GetKeyDown(KeyCode.B))
        {
            UIModule.Instance.ShowUI<UI_BagListView>();
        }
    }

    private void NewGameTime()
    {
        gameSecond = 0;
        gameDay = 1;
        gameMonth = 1;
        gameYear = 2022;
        gameSeason = Season.春天;
        daysInCurrentSeason = GetSeasonDays(gameSeason);
        currentDayPhase = GetCurrentDayPhase();

        RollNewWeather(true);
        UpdateInspectorDisplay();
    }

    public Season GetCurrentSeason()
    {
        return gameSeason;
    }
}